Go Nuts!
First impressions of Go
Over the past couple of weeks, I've been picking up Go, a language created by some hackers at Google that was released last year.
I started learning it because I really wanted to have a language in my toolbox that can take advantage of multiple processors and has C-like performance. Of course I could just learn C or C++, but both of these languages really annoy me, their lack of garbage collection, unsafe pointer operations all over the place, long compilation cycles, brain damaging type-system, etc. Of course there are still places where you absolutely have to use these languages, and they have proven their worth in a lot of instances, but we really should be creating a better future.
Naturally, I'm learning this language with a view biased from my previous experiences, and so I thought it might be fun to write down what exactly is going on during this process.
Let's start with the things I found annoying, unintuitive, and weird.
No eval. There is next to no support for metaprogramming, you have to write everything and cannot generate code during runtime. There is a reflect library that helps a bit, but overall the philosophy of Go is explicit over implicit.
Methods, which you can define on your own types, don't have an implicit receiver, there isn't even an equivalent to self
or this
that you might expect. Some people love it, others hate it, and I'm still torn between these two extremes.
No Generics. The closest you can come is having collections of the type interface{}
and converting to/from it when accessing the collection. This has some performance implications and makes your code harder to reason about. Currently there are some attempts, most notably gotgo, that try to provide an equivalent of C++ templates for Go. Still a messy business, and not something newcomers would be aware of.
No methods on Interfaces. Given that you have something that satisfies an Interface, it would be a logical step to be able to define methods on the Interface itself that only relies on methods described in it. There are more or less ugly workarounds, like embedding your Interface into a struct, defining toplevel functions that take the interface as an argument, or making the method part of the interface and duplicating the code in all types implementing it.
Struct fields cannot be accessed through an Interface, you either have to define methods in the interface to access them, which results in lots of GetFoo
, SetFoo
and code duplication, but is necessary anyway if you want your struct fields to be read-only or write-only anyway.
All in all, Go certainly doesn't seem to be a language for DRY enthusiasts. It's certainly possible to achieve some amount of code reuse, but it's as if the language drives you into another direction so you always have to consciously steer into the other direction.
Quite obviously, the language developers try to get mindshare and users from the C and C++ camps. The mailing list has many mails from people asking why things are kind of like what they are used to, but subtly different. I've even heard complaints about the side on which types are specified, and the FAQ has a whole section for people coming from C or from C++. Neither of which are particularly useful for me, as I've never written anything in these languages.